package game;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Vector;

public class agent {

	DictionaryTable dt = new DictionaryTable("trimmedList.txt");
	EnglishScrabbleScorer myScorer = new EnglishScrabbleScorer();
	BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	TileRack rack = new TileRack();
	Bag bag = new Bag();	
	
	boolean firstAsk = true;

	public static int bet, score;
	public int riskTolerance, moodiness, mood, bankRoll, handValue, number,difficultyInt;
	
	
	String easy = "easy", medium = "medium", hard = "hard", difficulty, bestWord, numberIn, word;
	
    /*
     * Constructor for the computer agent which needs mood/risk tolerance.
     * @param none
     */	
	public agent(int br, int rt, int moo) {
		this.bankRoll = br;
		this.riskTolerance = rt;
		this.mood = moo;
	}

    /*
     * Constructor for the player agent, which doesn't need mood/risk tolerance.
     * @param The agen't initial bankroll.
     */
	public agent(int br){
		this.bankRoll = br;
	}
	
    /*
     * Takes from the agent's bankroll.
     * @param The int amount to be subtracted.
     */
	
	public void takeFromBankRoll(int amount) {
    	bankRoll = (bankRoll - amount);  
    }
        
    /*
     * Adds to the agent's bankroll.
     * @param The int amount to be added.
     */
	
    public void addToBankRoll(int amount) {
         bankRoll = (bankRoll + amount);
    }
	
    /*
     * Returns true if the player's bankroll is equal to zero.
     * @param none
     */
    
    public boolean isBankrupt() {
        return bankRoll == 0;
    }
       
    /*
     * Returns the agent's current bankroll.
     * @param none
     */
    
    public int getCurrentBankRoll() {
        return bankRoll;
    }
	
    /*
     * Asks the user for a textual input, parses that to an int and then returns that as the max length of words the computer can make. 
     * @param none
     */
    
    public int setDifficulty() throws IOException{
    	if (firstAsk){
    	System.out.println("Which difficulty do you want to play the game on? \nPlease enter: easy/medium/hard");
    	}
    	try {
    		difficulty = br.readLine().toLowerCase();
                        
            if(difficulty.equals(easy)) difficultyInt = 3;
            else if(difficulty.equals(medium)) difficultyInt = 6;
            else if(difficulty.equals(hard)) difficultyInt = 8;
    		
            else if (!(difficulty.equals(easy))||!(difficulty.equals(medium))||!(difficulty.equals(hard))){
            	firstAsk = false;
                System.out.println("You didn't enter a valid difficulty. Please try again.");
                setDifficulty();
            }
        		           
        } catch (NumberFormatException nFE) {
        	System.out.println("That wasn't a valid number! Please try again!");
        	setDifficulty();
        }
    	return difficultyInt;
    }
    

    /*
     * Generates the best possible word of length difficulty and the input of the rack
     * @param none
     */
    public String bestWord(){
    	
        return word = dt.getBestWordIn(difficultyInt, rack.returnString());
    }
    
    /*
     * Gets the score of the computer agent's word which is generated from bestWord().
     * @param none
     */
    public int getScore(){

        return handValue = myScorer.StringScore(bestWord());
    }
    
    /*
     * Gets the easy/medium/hard input from the user to determine difficulty.
     * @param none
     */
    public int getBetInput() throws IOException {
        try {
            numberIn = br.readLine();
            number = Integer.parseInt(numberIn);

        } catch (NumberFormatException nFE) {
            
            System.out.println("That wasn't a valid number! Please try again!");
            getBetInput();
        }
        return number;
    }

    /*
     * Gets the word from the user and checks that the user has entered a valid word.
     * @param none
     */
    public String getWordInput() {
    	Vector words = validWords();
        try {
            word = br.readLine().toLowerCase();
            if (!words.contains(word)) {
                System.out.println("You didn't enter a valid word. Please try again.");
                getWordInput();
            }
            
            
        } catch (IOException e) {
            System.out.println("Error!");
        }
        return word;
    }

    /*
     * Scores the word which the user inputs.
     * @param The String input which is recieved from getWordInput().
     */    
    public int getScore(String input) {
        word = input;
        if (dt.containsWord(word)) {
            return handValue = myScorer.StringScore(word);
        }
        
        return handValue;
    }
    
    /*
     * Generates a vector of all of the valid words possible from the player's rack, for checking to see if user has entered a valid word.
     * @param The String input which is recieved from getWordInput().
     */    
    public Vector<String> validWords(){
    	Vector <String> v = new Vector<String>();

    	for (int i = 2; i <= 8; i++){
    		v.addAll(this.dt.getAllWordsOfLength(i, this.rack.returnString()));
    	}
    	return v;
    }
    
    /*
     * Determines if the agent should fold.
     * @param none
     */
    public boolean shouldFold() {
        int rand = (int) (Math.random() * 100);
        return (rand > riskTolerance + this.getScore());
     }
    
    /*
     * Determines if the agent should raise.
     * @param none
     */
    public boolean shouldRaise() {
        int rand = (int) (Math.random() * 100);
        
        
        return (rand < (riskTolerance + mood + this.getScore()));
     }
    
    /*
     * Determines if the agent should check.
     * @param none
     */
    public boolean shouldCheck() {
        return (shouldFold() == shouldRaise());
     }
    
    
    /*
     * The computer agent makes a decision based off should raise/fold/check. 
     * **Should return an enum type**
     * @param none
     */
    public String makeDecision(){//boolean c,boolean f,boolean r){
        boolean c = shouldCheck();
        boolean f = shouldFold();
        boolean r = shouldRaise();
        
        String raise = "raise", fold = "fold", check = "check";
        
        if (f&&r){
            System.out.println("Player will check");
            return check;
        }
        else if (f){
            System.out.println("Player will fold");
            return fold;
        }
        else{
            System.out.println("Player will raise");
            return raise;
        }
    
}
}

